package com.ColonyCount.View;

import java.util.ArrayList;
import java.util.List;

import com.ColonyCount.OnThresholdChangedListener;
import com.ColonyCount.Image.Histogram;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.widget.ImageView;

public class HistogramView extends ImageView {
	
	List<OnThresholdChangedListener> thresholdChangedListeners = new ArrayList<OnThresholdChangedListener>();
	
	
	Bitmap bitmap;
	Canvas canvas;
	int threshold = 255;

	boolean movingMin = false;
	boolean movingMax = false;
	float lastX;

	int lineTouchRadius;
    int histogramHeight; 
    int histogramWidth;
	int margin = 5;
	int midmargin = 1;
    int colorBarHeight = 6 ;
	int width;
	int height;
    	
    Histogram histogram;

	public HistogramView(Context context) 
	{
		super(context);
		Initialize();
	}
	
	public HistogramView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        Initialize();
    }
	
	private void Initialize()
	{
		DisplayMetrics dm = getResources().getDisplayMetrics();
		
		height = (int)((float)dm.densityDpi*0.4f); 
		width = dm.widthPixels;
		
		histogramHeight = height - 2*margin - midmargin - colorBarHeight;
	    
	    histogramWidth = width - 2*margin;	
	    lineTouchRadius = (int)((float)dm.densityDpi*0.2f); 
	    	
		bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
		canvas = new Canvas(bitmap);
		setImageBitmap(bitmap);
		UpdateHistogramView();
	}
	
	public void registerThresholdChangedListener(OnThresholdChangedListener handler)
	{
		thresholdChangedListeners.add(handler);
	}
	
	public void unregisterThresholdChangedListener(OnThresholdChangedListener handler)
	{
		thresholdChangedListeners.remove(handler);
	}
	
	public void setThreshold(int threshold)
	{
		this.threshold = threshold;
		UpdateHistogramView();
	}

	public void setHistogram(Histogram histogram)
	{
		this.histogram = histogram;
		UpdateHistogramView();
	}

	@Override
	protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
	{
		 setMeasuredDimension(width, height);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		
		//if(v == (ImageView) findViewById(R.id.histogramView))
		{
			float x = event.getX() - margin;
			switch(event.getAction())
			{
			case MotionEvent.ACTION_DOWN:
				
				if(Math.abs(threshold - (int)x) < lineTouchRadius)
				{
					movingMax = true;
					break;
				}
				
				break;
			case MotionEvent.ACTION_MOVE:
				float delta = x - lastX;
				if(movingMax)
				{
					threshold += (int)delta;
					threshold = clamp(threshold, 0, 255);
				}			
				
				UpdateHistogramView();
				ThresholdChanged(threshold);
				break;
			case MotionEvent.ACTION_UP:
				movingMin = false;
				movingMax = false;
				ThresholdChanged(threshold);
				break;
			}
			lastX = x;
			return true;
		}
		//return false;
	}
	
	void ThresholdChanged(int threshold)
	{
		for(OnThresholdChangedListener listener : thresholdChangedListeners)
		{
			listener.onThresholdChanged(threshold);
		}
	}
	
	void UpdateHistogramView()
	{
		Paint mPaintBackground = new Paint();
		mPaintBackground.setStyle(Paint.Style.FILL);
		mPaintBackground.setColor(Color.LTGRAY);

		canvas.drawRect(0,0,width, height, mPaintBackground);
		
		// Histogram
		if(histogram != null)
		{
			int[] histogramValues = histogram.values;
			int startX = margin;
			int histogramY = histogramHeight + margin;
			int colorBarY = histogramY + midmargin + colorBarHeight;
			float heightFactor = (float)histogramHeight/(float)histogram.maxValue;
			float widthFactor = (float)histogramWidth/255;
			widthFactor = 1;
			Paint mPaintHistogram = new Paint();
			mPaintHistogram.setStyle(Paint.Style.FILL);
			for(int i=0; i < histogramValues.length; i++)
			{
				mPaintHistogram.setColor(Color.BLACK);
				int x = (int)((float)i*widthFactor) + startX;
				int barHeight = (int) Math.ceil((float)(histogramValues[i])*heightFactor);
				canvas.drawLine(x, histogramY, x, histogramY - barHeight, mPaintHistogram);

				int color = 0xFF000000 | i << 16 | i << 8 | i;
				mPaintHistogram.setColor(color);
				canvas.drawLine(x, colorBarY, x, colorBarY - colorBarHeight, mPaintHistogram);
			}
		}
		 
		// Threshold lines
		Paint mPaintThreshold = new Paint();
		mPaintThreshold.setStyle(Paint.Style.FILL);
		mPaintThreshold.setColor(Color.GREEN);
		mPaintThreshold.setStrokeWidth(3);
		
		int min = 0 + margin;
		int max = threshold + margin;

		// Draw selection line
		canvas.drawLine(max, margin, max, height - margin, mPaintThreshold);
		
		// Draw overlay
		mPaintThreshold.setAlpha(60);
		canvas.drawRect(min, margin, max, height - margin, mPaintThreshold);
	
		Paint mPaintText = new Paint();
		mPaintText.setStyle(Paint.Style.FILL);
		mPaintText.setColor(Color.WHITE);
		mPaintText.setTextSize(10);
		canvas.drawText("" + threshold, max, 18, mPaintText);
		
		setImageBitmap(bitmap);
		
		invalidate();
	}
	
	
	
	
	int clamp(int value, int min, int max)
	{
		if(value > max)
			return max;
		if(value < min)
			return min;
		return value;
	}
}
